package com.ken.apollo.controller.backs;

import com.ken.apollo.commons.result.R;
import com.ken.apollo.service.ImageProcessingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * 后台图片管理控制器
 * 
 * @author Ken
 * @since 2024-01-01
 */
@Controller
@RequestMapping("/backs")
@Slf4j
public class ImageManagerController {

    @Value("${upload.path}")
    private String uploadPath;
    
    @Autowired
    private ImageProcessingService imageProcessingService;

    /**
     * 图片管理页面
     */
    @GetMapping("/image_manager")
    public String imageManager() {
        return "backs/image_manager";
    }

    /**
     * 图片增强工具页面
     */
    @GetMapping("/image_enhancer")
    public String imageEnhancer() {
        return "backs/image_enhancer";
    }

    /**
     * 获取图片列表
     */
    @GetMapping("/api/image/list")
    @ResponseBody
    public R<List<ImageFileInfo>> getImageList() {
        try {
            File uploadDir = new File(uploadPath);
            if (!uploadDir.exists()) {
                return R.success(new ArrayList<>());
            }

            File[] files = uploadDir.listFiles((dir, name) -> {
                String lowerName = name.toLowerCase();
                return lowerName.endsWith(".jpg") || lowerName.endsWith(".jpeg") || 
                       lowerName.endsWith(".png") || lowerName.endsWith(".gif") || 
                       lowerName.endsWith(".bmp");
            });

            List<ImageFileInfo> imageList = new ArrayList<>();
            if (files != null) {
                for (File file : files) {
                    ImageFileInfo info = new ImageFileInfo();
                    info.setFilename(file.getName());
                    info.setSize(file.length());
                    info.setLastModified(file.lastModified());

                    // 获取图片尺寸信息
                    ImageProcessingService.ImageInfo imageInfo = imageProcessingService.getImageInfo(file.getName());
                    if (imageInfo != null) {
                        info.setWidth(imageInfo.getWidth());
                        info.setHeight(imageInfo.getHeight());
                    }

                    imageList.add(info);
                }
            }

            // 按修改时间排序（最新的在前）
            imageList.sort((a, b) -> Long.compare(b.getLastModified(), a.getLastModified()));

            return R.success(imageList);

        } catch (Exception e) {
            log.error("获取图片列表失败", e);
            return R.fail("获取图片列表失败: " + e.getMessage());
        }
    }

    /**
     * 删除图片
     */
    @DeleteMapping("/api/image/delete")
    @ResponseBody
    public R<String> deleteImage(@RequestParam String filename) {
        try {
            File file = new File(uploadPath, filename);
            if (!file.exists()) {
                return R.fail("文件不存在");
            }

            if (file.delete()) {
                log.info("删除图片成功: {}", filename);
                return R.success("删除成功");
            } else {
                return R.fail("删除失败");
            }

        } catch (Exception e) {
            log.error("删除图片失败: {}", filename, e);
            return R.fail("删除失败: " + e.getMessage());
        }
    }

    /**
     * 批量删除图片
     */
    @DeleteMapping("/api/image/batch-delete")
    @ResponseBody
    public R<String> batchDeleteImages(@RequestParam String[] filenames) {
        try {
            int successCount = 0;
            int failCount = 0;

            for (String filename : filenames) {
                try {
                    File file = new File(uploadPath, filename);
                    if (file.exists() && file.delete()) {
                        successCount++;
                    } else {
                        failCount++;
                    }
                } catch (Exception e) {
                    log.error("删除图片失败: {}", filename, e);
                    failCount++;
                }
            }

            String message = String.format("批量删除完成，成功: %d, 失败: %d", successCount, failCount);
            log.info(message);
            return R.success(message);

        } catch (Exception e) {
            log.error("批量删除图片失败", e);
            return R.fail("批量删除失败: " + e.getMessage());
        }
    }

    /**
     * 获取存储统计信息
     */
    @GetMapping("/api/image/storage-stats")
    @ResponseBody
    public R<StorageStats> getStorageStats() {
        try {
            File uploadDir = new File(uploadPath);
            StorageStats stats = new StorageStats();
            
            if (!uploadDir.exists()) {
                return R.success(stats);
            }

            File[] files = uploadDir.listFiles();
            if (files != null) {
                long totalSize = 0;
                int imageCount = 0;
                
                for (File file : files) {
                    if (file.isFile()) {
                        totalSize += file.length();
                        String name = file.getName().toLowerCase();
                        if (name.endsWith(".jpg") || name.endsWith(".jpeg") || 
                            name.endsWith(".png") || name.endsWith(".gif") || 
                            name.endsWith(".bmp")) {
                            imageCount++;
                        }
                    }
                }
                
                stats.setTotalFiles(files.length);
                stats.setImageFiles(imageCount);
                stats.setTotalSize(totalSize);
                stats.setUploadPath(uploadPath);
                
                // 计算可用空间（简化实现）
                stats.setAvailableSpace(uploadDir.getFreeSpace());
            }

            return R.success(stats);

        } catch (Exception e) {
            log.error("获取存储统计信息失败", e);
            return R.fail("获取统计信息失败: " + e.getMessage());
        }
    }

    /**
     * 图片文件信息类
     */
    public static class ImageFileInfo {
        private String filename;
        private long size;
        private long lastModified;
        private int width;
        private int height;

        // Getters and Setters
        public String getFilename() { return filename; }
        public void setFilename(String filename) { this.filename = filename; }
        
        public long getSize() { return size; }
        public void setSize(long size) { this.size = size; }
        
        public long getLastModified() { return lastModified; }
        public void setLastModified(long lastModified) { this.lastModified = lastModified; }
        
        public int getWidth() { return width; }
        public void setWidth(int width) { this.width = width; }
        
        public int getHeight() { return height; }
        public void setHeight(int height) { this.height = height; }
    }

    /**
     * 存储统计信息类
     */
    public static class StorageStats {
        private int totalFiles = 0;
        private int imageFiles = 0;
        private long totalSize = 0;
        private long availableSpace = 0;
        private String uploadPath;

        // Getters and Setters
        public int getTotalFiles() { return totalFiles; }
        public void setTotalFiles(int totalFiles) { this.totalFiles = totalFiles; }
        
        public int getImageFiles() { return imageFiles; }
        public void setImageFiles(int imageFiles) { this.imageFiles = imageFiles; }
        
        public long getTotalSize() { return totalSize; }
        public void setTotalSize(long totalSize) { this.totalSize = totalSize; }
        
        public long getAvailableSpace() { return availableSpace; }
        public void setAvailableSpace(long availableSpace) { this.availableSpace = availableSpace; }
        
        public String getUploadPath() { return uploadPath; }
        public void setUploadPath(String uploadPath) { this.uploadPath = uploadPath; }
    }

    /**
     * 从远程链接下载图片
     */
    @PostMapping("/api/image/download")
    @ResponseBody
    public R<String> downloadImage(@RequestParam String imageUrl) {
        try {
            log.info("开始下载图片: {}", imageUrl);
            
            // 创建链接
            URL url = new URL(imageUrl);
            URLConnection connection = url.openConnection();
            connection.setConnectTimeout(10000); // 10秒连接超时
            connection.setReadTimeout(30000); // 30秒读取超时
            
            // 设置 User-Agent 避免被拒绝
            connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
            
            // 生成文件名
            String filename = UUID.randomUUID().toString().replace("-", "");
            
            // 根据内容类型确定文件扩展名
            String contentType = connection.getContentType();
            if (contentType != null) {
                if (contentType.contains("image/png")) {
                    filename += ".png";
                } else if (contentType.contains("image/gif")) {
                    filename += ".gif";
                } else if (contentType.contains("image/bmp")) {
                    filename += ".bmp";
                } else {
                    filename += ".jpg"; // 默认为jpg
                }
            } else {
                filename += ".jpg";
            }
            
            // 确保上传目录存在
            File uploadDir = new File(uploadPath);
            if (!uploadDir.exists()) {
                uploadDir.mkdirs();
            }
            
            // 下载文件
            File targetFile = new File(uploadDir, filename);
            try (InputStream in = connection.getInputStream();
                 FileOutputStream out = new FileOutputStream(targetFile)) {
                
                byte[] buffer = new byte[8192];
                int bytesRead;
                while ((bytesRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                }
            }
            
            log.info("图片下载成功: {} -> {}", imageUrl, filename);
            return R.success(filename, "图片下载成功");
            
        } catch (Exception e) {
            log.error("下载图片失败: {}", imageUrl, e);
            return R.fail("下载失败: " + e.getMessage());
        }
    }

    /**
     * 下载并处理图片
     */
    @PostMapping("/api/image/download-and-process")
    @ResponseBody
    public R<ProcessResult> downloadAndProcessImage(@RequestParam String imageUrl,
                                                   @RequestParam(defaultValue = "1920") int width,
                                                   @RequestParam(defaultValue = "1080") int height,
                                                   @RequestParam(defaultValue = "0.9") float quality) {
        try {
            // 首先下载图片
            R<String> downloadResult = downloadImage(imageUrl);
            if (downloadResult.getCode() != 200) {
                return R.fail("下载图片失败: " + downloadResult.getMessage());
            }
            
            String originalFilename = downloadResult.getData();
            
            // 获取原图信息
            ImageProcessingService.ImageInfo originalInfo = imageProcessingService.getImageInfo(originalFilename);
            if (originalInfo == null) {
                return R.fail("无法获取原图信息");
            }
            
            // 处理图片
            String processedFilename = imageProcessingService.resizeImage(originalFilename, width, height, quality);
            
            // 获取处理后的图信息
            ImageProcessingService.ImageInfo processedInfo = imageProcessingService.getImageInfo(processedFilename);
            if (processedInfo == null) {
                return R.fail("无法获取处理后的图信息");
            }
            
            // 构建结果
            ProcessResult result = new ProcessResult();
            result.setOriginalFilename(originalFilename);
            result.setOriginalWidth(originalInfo.getWidth());
            result.setOriginalHeight(originalInfo.getHeight());
            result.setOriginalSize(originalInfo.getFileSize());
            result.setProcessedFilename(processedFilename);
            result.setProcessedWidth(processedInfo.getWidth());
            result.setProcessedHeight(processedInfo.getHeight());
            result.setProcessedSize(processedInfo.getFileSize());
            
            log.info("图片下载并处理成功: {} -> {}", originalFilename, processedFilename);
            return R.success(result, "图片处理成功");
            
        } catch (Exception e) {
            log.error("下载并处理图片失败: {}", imageUrl, e);
            return R.fail("处理失败: " + e.getMessage());
        }
    }

    /**
     * 处理结果类
     */
    public static class ProcessResult {
        private String originalFilename;
        private int originalWidth;
        private int originalHeight;
        private long originalSize;
        private String processedFilename;
        private int processedWidth;
        private int processedHeight;
        private long processedSize;

        // Getters and Setters
        public String getOriginalFilename() { return originalFilename; }
        public void setOriginalFilename(String originalFilename) { this.originalFilename = originalFilename; }
        
        public int getOriginalWidth() { return originalWidth; }
        public void setOriginalWidth(int originalWidth) { this.originalWidth = originalWidth; }
        
        public int getOriginalHeight() { return originalHeight; }
        public void setOriginalHeight(int originalHeight) { this.originalHeight = originalHeight; }
        
        public long getOriginalSize() { return originalSize; }
        public void setOriginalSize(long originalSize) { this.originalSize = originalSize; }
        
        public String getProcessedFilename() { return processedFilename; }
        public void setProcessedFilename(String processedFilename) { this.processedFilename = processedFilename; }
        
        public int getProcessedWidth() { return processedWidth; }
        public void setProcessedWidth(int processedWidth) { this.processedWidth = processedWidth; }
        
        public int getProcessedHeight() { return processedHeight; }
        public void setProcessedHeight(int processedHeight) { this.processedHeight = processedHeight; }
        
        public long getProcessedSize() { return processedSize; }
        public void setProcessedSize(long processedSize) { this.processedSize = processedSize; }
    }
}